package com.tedu.api.io;

import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import org.junit.Test;

import java.io.*;

/**   流--专门处理传输数据为：文本
 *
 *  高级流--处理文本--->转换流
 *  “字符流”：针对读写抽象类【Reader抽象类】
 *
 *  节点流与字符流区别：单位进行区分，节点流最小单位：字节
 *                               字符流最小单位；字符【针对文本】
 *
 *  高级流【转换流】功能；处理文本内容
 *  字符流的子实现类：InputStreamReader 继承Reader抽象类 读入操作
 *                 OutputStreamWriter继承Writer抽象类 写出操作
 *  高级流--->转换流【字符流】 按照功能划分--->处理文本读写操作
 *  功能：处理节点流又可以被其他流所处理，类似于“转换器”效果
 */
public class IOSAPI {
    /**
     * 需求：从 API 文件中 写出 osw.txt文件---一行文本
     */
    @Test
    public void testOSW(){
        //1.所有的流全部置空
        FileOutputStream fos=null;   //低级流：搬运数据
        OutputStreamWriter osw=null; //高级流:“转换流 套低级流 套其他高级流”
        //2.捕获流的所有异常
        try {
            fos=new FileOutputStream("osw.txt");
            osw=new OutputStreamWriter(fos); //转换流
            //3.转换流中方法：write() 直接写出文本内容，不需要把文本转换为二进制
            //    高级流---转换流---字符流
            osw.write("双击666");
            osw.write("你好你好");
            osw.write("你好你好你好你好");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally { //必须关闭 有高级流 关 高级流
            if (osw!=null)
                try {
                    osw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
    /**
     * Writer抽象类---子实现类OutputStreamWriter 字符输出流 以字符形式写出
     * Reader抽象类---子实现类InputStreamReader 字符输入流  不是以字符形式读入
     *                                                   int  二进制值
     *                                                  【无法直接赋值】
     *高级流：针对转换流InputStreamReader无法直接读入字符串
     *BufferedWriter---直接套在转换流上高级流：缓冲输出流
     *BufferedReader---直接套在转换流上高级流：缓冲输入流
     *特点：可以按照形式进行读取字符串【换行文件读取完毕】
     *
     *转换流中出现异常：UnsupportedEncodingException编码集转换异常
     *        产生原因：转换流【字符输入/出流】指定编码集不对称
     *        IOException IO型大异常
     */
    @Test
    public void testISR() {
        //1.流置空---方便赋值以及关闭操作
        FileInputStream fis=null;
        InputStreamReader isr=null; //转换流指定编码集 无法读取字符串
        BufferedReader br=null;   //缓冲输入流：解决 读取字符串
        //2.捕获流异常
        try {
            fis=new  FileInputStream("osw.txt");
            isr=new InputStreamReader(fis,"UTF8");//转换流：字符输出流
            //转换流：字符输出流--功能：构造器第二个参数，添加编码集：UTF8 识别文字多：万
            br=new BufferedReader(isr);//缓冲输入流
            /**
             * readLine() 读取若干字符串，直到读完为止【没有换行符】
             *             读取数据返回值字符串
             *如果返回值不为null，表示所有数据没有读取完毕
             *           为null 表示数据读取完毕【没有换行符】
             */
            //①定义引用类型变量
            String line=null;
            //②【一直】读取一行文本保存line中判断line不为空--输出文本
            // (line=br.readLine())!=null
            while ((line= br.readLine())!=null){
                System.out.println(line);
            }
            String str=br.readLine();
            System.out.println("读取数据"+str);
        } catch (FileNotFoundException e){//文件不存在
            e.printStackTrace();
        } catch (UnsupportedEncodingException e){//编码集异常
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流高级流
            if(br!=null) {
                try {
                    br.close();
          } catch (IOException e) {
                    e.printStackTrace();
         }
        }
      }
    }
    /**
     * 作业 2 读取 IOSAPI.java 文件到控制台,指定编码及：UTF8 万国码
     *        提示：按照从上到下执行逻辑---标准流：IO+异常捕获
     */
    @Test
    public void testHomeWork2(){
        //1.创建低级流---针对 读操作  【找到ISOAPI.java】
        FileInputStream fis=null;
        InputStreamReader isr=null;
        BufferedReader br=null;
        //maven项目----src\main\java\com\tedu\api\io\IOSAPI.java
        try {
            fis=new FileInputStream("src"+File.separator+"main"
               +File.separator+"java" +File.separator+"com"
               +File.separator+"tedu"+File.separator+"api"
               + File.separator+"io" +File.separator+"IOSAPI.java");
            //2.创建转换流----指定编码及：UTF8 【不能直接输出字符串】
            isr=new InputStreamReader(fis,"UTF8");
            //3.【能直接输出字符串】创建缓冲？？流
            br=new BufferedReader(isr);
            //创建保存每行字符串的变量、
            String line=null;
            //5.一直  读取字符串，不等于null  有字符串--同时写出
            while((line= br.readLine())!=null) {
                System.out.println(line);
            }
            String str=br.readLine();
            System.out.println(str);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        } finally {
            //6.关闭流
         if(br!=null)
             try {
                 br.close();
                } catch (IOException e) {
                 e.printStackTrace();
            }
        }

    }

    /**
     * 高级流---特殊：①直接创建高级流对象
     *              ②不是成对---BufferedReader
     *              ③直接写出文本
     *PrintWriter 字符输出流
     *需求：从程序写出 pw.txt 文件 指定编码集：UTF8，输出几行文本
     */
    @Test
    public void testPW() throws FileNotFoundException, UnsupportedEncodingException {
        //创建高级流，套三个流 FileOutStream 低级流 搬运数据
        //                  OutputStreamWriter 高级流 转换流 指定编码集
        //                BufferedWriter  高级流 套在转换流上 效率写
        PrintWriter pw=new PrintWriter("pw.txt","utf8");
        //print()输出一行文本，不能换行 println（）输出一行文本，能换行
        pw.print("你就是");
        pw.println("我的小可爱");
        pw.close();
    }
}
















